#!/usr/bin/env python2
import os
import sys
import errno
import uuid
import getopt
import subprocess
import time
import re

from utils import Exp, _exec_pipe, _exec_pipe1, _put_remote, _exec_system, _exec_shell, _derror, _isip, _exec_remote

def usage():
    print ("usage:")
    print (sys.argv[0] + " --list")
    print (sys.argv[0] + " --discovery ip")
    print (sys.argv[0] + " --login ip iqn")
    print (sys.argv[0] + " --logout [ip iqn]")
    print (sys.argv[0] + " [--verbose -v] [--help -h]")

class Iscsi():
    def __init__(self, v=False):
        self.verbose = v
        self.sess = None

    def list(self):
        list = []
        try:
            if self.sess is None:
                self.sess, err = _exec_pipe1(['iscsiadm', '-m', 'session', '-P3'], p=self.verbose)
            res = self.sess
            for line in res.splitlines():
                m1 = re.match("Target:\s*(\S+)", line)
                if m1 is not None:
                    iqn = m1.group(1)
                m1 = re.match("\s*Iface Transport: (\S+)", line)
                if m1 is not None:
                    iface = m1.group(1)
                m1 = re.match("\s*Attached scsi disk\s*(\S+)", line)
                if m1 is not None:
                    dev = m1.group(1)
                    list.append((iqn, iface, dev))
        except Exp, e:
            self.sess = ''
            pass

        return list

    def discovery(self, ip):
        try:
            res = _exec_pipe(['iscsiadm', '-m', 'discovery', '-t', 'sendtargets', '-p', ip], p=self.verbose)
            for line in res.splitlines():
                m = re.match(".*(iqn.*:\S+)", line)
                if m is not None:
                    print m.group(1)
        except Exp, e:
            _derror(e.err)
            exit(e.errno)

    def login(self, ip, iqn):
        try:
            res = _exec_pipe(['iscsiadm', '-m', 'node', '-T', iqn, '-p', ip, '--login'], p=self.verbose)
        except Exp, e:
            _derror(e.err)
            exit(e.errno)

    def getdev(self, tgt):
        devs = []
        lun = ""
        tag = False
        try:
            res = _exec_pipe(['iscsiadm', '-m', 'session', '-P3'], p=self.verbose)
            for line in res.splitlines():
                if line.startswith('Target:'):
                    tag = False
                    m = re.match('Target:.*:%s' % tgt, line)
                    if m:
                        tag = True
                        #print m.group(0)
                else:
                    m = re.match("\s*scsi\d+ Channel \d+ Id \d+ Lun: (\d+)", line)
                    if m:
                        lun = m.group(1)
                    m = re.match("\s*Attached scsi disk (\w+)\s*State: running", line)
                    if m:
                        dev = m.group(1)
                        #print "lun",lun,"dev",dev
                        if tag:
                            devs.append((lun, dev))
        except:
            pass

        return devs

    def logout(self, ip, iqn):
        if (ip != "" and iqn != ""):
            try:
                res = _exec_pipe(['iscsiadm', '-m', 'node', '-T', iqn, '-p', ip, '--logout'], p=self.verbose)
            except Exp, e:
                _derror(e.err)
                exit(e.errno)
        else:
            try:
                res = _exec_pipe(['iscsiadm', '-m', 'node', '-u'], p=self.verbose)
            except Exp, e:
                _derror(e.err)
                exit(e.errno)

    def login_tgt(self, ip, tgt):
        target = ""

        res = _exec_pipe(['iscsiadm', '-m', 'discovery', '-t', 'sendtargets', '-p', ip], p=self.verbose)
        m = re.findall("iqn.*:%s"%tgt, res)
        if m:
            target = m[0]

        res = _exec_pipe(['iscsiadm', '-m', 'node', '-T', target, '-p', ip, '--login'], p=self.verbose)


def main():
    ip = ""
    iqn = ""
    op = ""
    ext = None
    verbose = False

    try:
        opts, args = getopt.getopt(
                sys.argv[1:],
                'hv', ['help', 'verbose', 'list', 'login=', 'logout', 'discovery=']
                )
    except getopt.GetoptError, err:
        print str(err)
        usage()
        exit(errno.EINVAL)

    for o, a in opts:
        if o in ('-h', '--help'):
            usage()
            exit(0)
        elif o in ('-v', '--verbose'):
            verbose = True
            exit(0)
        elif o in '--list':
            op = o
        elif o in '--login':
            op = o
            if (len(sys.argv) < 4):
                _derror("need ip and iqn")
                exit(errno.EINVAL)
            ip = sys.argv[2]
            iqn = sys.argv[3]
        elif o in '--logout':
            op = o
            if (len(sys.argv) == 4):
                ip = sys.argv[2]
                iqn = sys.argv[3]
        elif o in '--discovery':
            op = o
            if _isip(a):
                ip = a
            else:
                _derror("ip %s invalid" % a)
        else:
            usage()
            exit(errno.EINVAL)

    try:
        iscsi = Iscsi(verbose)
    except Exp, e:
        raise
        _derror(e.err)
        exit(e.errno)

    if (op == "--list"):
        list = iscsi.list()
        for i in list:
            print ("%s: %s /dev/%s" % (i[1], i[0],i[2]))
    elif (op == "--discovery"):
        iscsi.discovery(ip)
    elif (op == "--login"):
        iscsi.login(ip, iqn)
    elif (op == "--logout"):
        iscsi.logout(ip, iqn)
    else:
        usage()
        exit(errno.EINVAL)

if __name__ == '__main__':
    if (len(sys.argv) == 1):
        usage()
    else:
        main()
